﻿#ifndef __WINDOWCONTAINER_H__
#define __WINDOWCONTAINER_H__

#include "./winhdr.h"
#include "./winupdate.h"
#include "./windib.h"
#include "../inputhelper.h"
#include "../container.h"
#include <string>

namespace MiniUI
{

class WindowContainer : public Container,
                        public CWindowImpl<WindowContainer>,
                        public Creator<WindowContainer>
{
    friend class Creator<WindowContainer>;
public:
    WindowContainer();
    virtual ~WindowContainer();
public:
    virtual bool CreateContainer(const Type::MiniRect& rect);
    virtual void DestroyContainer();
    virtual void* GetHost();
    virtual void Hide();
    virtual void Show();
    virtual void SetRect(const Type::MiniRect& rect);
    virtual void GetRect(Type::MiniRect& rect) const;
    virtual void SetPos(const Type::MiniPoint& pt);
    virtual void GetPos(Type::MiniPoint& pt) const;
    virtual void SetSize(const Type::MiniSize& sz);
    virtual void GetSize(Type::MiniSize& sz) const;

    virtual void SetCaption(const char* szCaption);
    virtual void SetBorder(const Type::MiniRect& border);
    virtual void SetMaxSize(const Type::MiniSize& size);
    virtual void SetMinSize(const Type::MiniSize& size);
    virtual void SetTopMost(bool bTopMost);
    virtual bool IsTopMost();
    virtual void SetForegroundWindow();
    virtual void GetCursorPos(Type::MiniPoint& pt);
    virtual void SetCursor(CursorType cursor, void* customCursor = nullptr);
public:
    DECLARE_WND_CLASS(L"MiniWin")

    BEGIN_MSG_MAP_EX(WindowContainer)
        MSG_WM_CREATE(OnCreate)
        MSG_WM_DESTROY(OnDestroy)
        MSG_WM_CLOSE(OnClose)
        MSG_WM_PAINT(OnPaint)
        MSG_WM_ERASEBKGND(OnEraseBkgnd)
        MSG_WM_ACTIVATE(OnActivate)
        MSG_WM_SETCURSOR(OnSetCursor)
        MSG_WM_SIZE(OnSize)
        MSG_WM_MOVE(OnMove)
        MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
        MSG_WM_SETTINGCHANGE(OnSettingChange)
        MSG_WM_ENTERSIZEMOVE(OnEnterSizeMove)
        MSG_WM_ENTERSIZEMOVE(OnExitSizeMove)
        //Mouse
        MSG_WM_MOUSEMOVE(OnMouseMove)
        MSG_WM_MOUSELEAVE(OnMouseLeave)
        MSG_WM_MOUSEWHEEL(OnMouseWheel)
        //LButton
        MSG_WM_LBUTTONDOWN(OnLButtonDown)
        MSG_WM_LBUTTONUP(OnLButtonUp)
        MSG_WM_LBUTTONDBLCLK(OnLButtonDown)
        //RButton
        MSG_WM_RBUTTONDOWN(OnRButtonDown)
        MSG_WM_RBUTTONUP(OnRButtonUp)
        MSG_WM_RBUTTONDBLCLK(OnRButtonDown)
        //MButton
        MSG_WM_MBUTTONDOWN(OnMButtonDown)
        MSG_WM_MBUTTONUP(OnMButtonUp)
        MSG_WM_MBUTTONDBLCLK(OnMButtonDown)
        //XButton
        MSG_WM_XBUTTONDOWN(OnXButtonDown)
        MSG_WM_XBUTTONUP(OnXButtonUp)
        MSG_WM_XBUTTONDBLCLK(OnXButtonDown)
        //NC
        MSG_WM_NCCALCSIZE(OnNcCalcSize)
        MSG_WM_NCHITTEST(OnNcHitTest)
        MSG_WM_NCPAINT(OnNcPaint)
        MSG_WM_NCACTIVATE(OnNcActivate)
        //Message Handler
        MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnInputMessage)
        MESSAGE_HANDLER(WM_KEYDOWN, OnInputMessage)
        MESSAGE_HANDLER(WM_KEYUP, OnInputMessage)

        MESSAGE_HANDLER(WM_CHAR, OnInputMessage)
        MESSAGE_HANDLER(WM_SYSCHAR, OnInputMessage)
        MESSAGE_HANDLER(WM_SYSKEYDOWN, OnInputMessage)
        MESSAGE_HANDLER(WM_SYSKEYUP, OnInputMessage)

        MESSAGE_HANDLER(WM_IME_SETCONTEXT, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_STARTCOMPOSITION, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_COMPOSITION, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_CONTROL, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_ENDCOMPOSITION, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_COMPOSITIONFULL, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_NOTIFY, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_SELECT, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_CHAR, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_REQUEST, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_KEYDOWN, OnInputMessage)
        MESSAGE_HANDLER(WM_IME_KEYUP, OnInputMessage)
    END_MSG_MAP()
private:
    int OnCreate(LPCREATESTRUCT lpCreateStruct);
    void OnDestroy();
    void OnClose();
    void OnPaint(CDCHandle dc);
    BOOL OnEraseBkgnd(CDCHandle dc);
    void OnActivate(UINT uState, BOOL bMinimized, HWND hWnd);
    BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message);
    void OnSize(UINT nType, CSize size);
    void OnMove(CPoint ptPos);
    void OnGetMinMaxInfo(LPMINMAXINFO lpMMI);
    void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
    void OnEnterSizeMove();
    void OnExitSizeMove();
    //Mouse
    void OnMouseMove(UINT nFlags, CPoint point);
    void OnMouseLeave();
    BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint point);
    //LButton
    void OnLButtonDown(UINT nFlags, CPoint point);
    void OnLButtonUp(UINT nFlags, CPoint point);
    //RButton
    void OnRButtonDown(UINT nFlags, CPoint point);
    void OnRButtonUp(UINT nFlags, CPoint point);
    //MButton
    void OnMButtonDown(UINT nFlags, CPoint point);
    void OnMButtonUp(UINT nFlags, CPoint point);
    //XButton
    void OnXButtonDown(int fwButton, int dwKeys, CPoint point);
    void OnXButtonUp(int fwButton, int dwKeys, CPoint point);
    //NC
    LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam);
    UINT OnNcHitTest(CPoint point);
    void OnNcPaint(CRgn rgn);
    BOOL OnNcActivate(BOOL bActive);
    //Input
    LRESULT OnInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
protected:
    virtual void Update(const Type::MiniRect& rect);
    virtual void SyncRect();
private:
    WinDIB m_dib;
    bool m_bMouseEnter;
    BOOL m_bTrackingMouse;
    HCURSOR m_hCursor;
    MiniUI::UpdateWindow m_updateWindow;
    Type::MiniRect m_rcUpdate;
    Type::MiniRect m_border;
    Type::MiniSize m_szMax;
    Type::MiniSize m_szMin;

};

}

#endif